~{define "public/commonJS"}~
<script>
    // 将字符串编码为 Base64
    function toBase64(str) {
        const utf8Str = new TextEncoder().encode(str);
        return btoa(String.fromCharCode.apply(null, utf8Str));
    }

    // 将 字符串 转换为 URL Safe Base64 编码
    function toUrlSafeBase64(str) {
        let base64Str = toBase64(str);
        return base64Str.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
    }

    // 将 URL Safe Base64 编码转换为标准 Base64 编码
    function fromUrlSafeBase64(urlSafeBase64Str) {
        let base64Str = urlSafeBase64Str.replace(/-/g, '+').replace(/_/g, '/');
        while (base64Str.length % 4) {
            base64Str += '=';
        }
        return fromBase64(base64Str);
    }

    // 将 Base64 解码为字符串
    function fromBase64(base64Str) {
        const binaryStr = atob(base64Str);
        const utf8Arr = new Uint8Array(binaryStr.length);
        for (let i = 0; i < binaryStr.length; i++) {
            utf8Arr[i] = binaryStr.charCodeAt(i);
        }
        return new TextDecoder().decode(utf8Arr);
    }

    // 测试
    // const originalStr = "你好，世界！";
    // const base64Str = toBase64(originalStr);
    // const urlSafeBase64Str = toUrlSafeBase64(base64Str);
    // console.log(urlSafeBase64Str); // 编码后的 URL Safe Base64 字符串

    // const standardBase64Str = fromUrlSafeBase64(urlSafeBase64Str);
    // const decodedStr = fromBase64(standardBase64Str);
    // console.log(decodedStr); // 解码后的原始字符串
</script>
<script>
    // 复制接龙链接
    function makeJielongLink(jielongItem) {
        let url = window.location.protocol + '//' + window.location.host + '/jl/' + toUrlSafeBase64(jielongItem.ID);
        let user = jielongItem.CreatorName + '(' + jielongItem.CreatorAccount + ')';
        let title = `${user}发起的接龙 主题：${jielongItem.Theme} ${url}`;
        let link = makeYouduHideLink(title, url)
        window.clipboard.copy(link, '链接已复制到剪贴板');
    }
</script>
<script>
    // 生成有度隐式链接
    function makeYouduHideLink(title, url, action = 1, openmodel = 2) {
        // 构造有度隐式链接
        let obj = JSON.stringify({
            title: title,
            url: url,
            action: action,
            openmodel: openmodel
        });
        let link = `#link#${obj}#link#`
        console.log('有度隐式链接', link);
        return link;
    }
</script>
<script>
    // 时间格式化
    dateFormat = function (time, fmt = 'yyyy-MM-dd HH:mm:ss', tz = 'Asia/Shanghai') {
        var date = new Date(time)
        // 将时间转换为东八区
        date = new Date(date.toLocaleString('en-US', { timeZone: tz }));
        var o = {
            'M+': date.getMonth() + 1, // 月份
            'd+': date.getDate(), // 日
            'H+': date.getHours(), // 小时
            'm+': date.getMinutes(), // 分
            's+': date.getSeconds(), // 秒
            'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
            S: date.getMilliseconds() // 毫秒
        }
        if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
        for (var k in o) {
            if (new RegExp('(' + k + ')').test(fmt)) {
                fmt = fmt.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length))
            }
        }
        return fmt
    }
</script>
<script>
    // 模拟分页
    function paginate(array, pageNumber, pageSize = 10) {
        const startIndex = (pageNumber - 1) * pageSize;
        const endIndex = startIndex + pageSize;
        return array.slice(startIndex, endIndex);
    }
</script>
<script>
    // 判断是否手机端
    function isMobile() {
        return window.matchMedia("(max-width: 512px)").matches;
    }
</script>
<script>
    // 获取url参数
    function getUrlParam(name) {
        var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
        var r = window.location.search.substr(1).match(reg);  //匹配目标参数
        if (r != null) return unescape(r[2]); return null; //返回参数值
    }
</script>
<script>
    // 提供一个参考数字，根据数字的字符数量，自动给第二个参数的数值左边自动补零，确保位数一致性
    function zeropad(numNow, numNeed) {
        let len1 = numNow.toString().length;
        let len2 = numNeed.toString().length;
        let numNew = numNeed.toString();
        // debugger
        if (len2 === 1 && len1 < 3) {
            return "0" + numNew;
        }
        if (len1 === 1) {
            return numNew;
        }
        if (len1 <= len2) {
            return numNew;
        }
        while (len1 > len2) {
            numNew = "0" + numNew;
            len2++;
        }
        return numNew;
    }

</script>
<script>
    // 复制功能
    window.clipboard = {
        copy(text, tip = '复制成功') {
            if (!window.$textareaForClipboard) {
                window.$textareaForClipboard = document.createElement('textarea');
                $textareaForClipboard.id = '$textareaForClipboard';
                $textareaForClipboard.style.top = '-500px';
                $textareaForClipboard.style.position = 'absolute';
                document.body.appendChild($textareaForClipboard);
            }
            $textareaForClipboard.value = text;
            $textareaForClipboard.select();
            document.execCommand('Copy');
            app.$message.success(tip);
        },
    }

</script>
<script>
    // 封装 fetch 请求函数
    async function fetchGet(url, options = {}) {
        // 定义返回结果的 key，用于统一处理返回结果
        var resKeys = {
            code: 'code',
            msg: 'msg',
            data: 'data',
            total: 'total',
        };
        var resSuccCode = 0;// 定义成功的返回码

        const defaultHeaders = {
            'AccessToken': '~{.AccessToken}~', // 替换为你的实际访问令牌
            'Content-Type': 'application/json'
        };

        // 合并用户传入的 headers 和默认 headers
        const headers = new Headers({
            ...defaultHeaders,
            ...options.headers
        });

        // 构建请求选项
        const fetchOptions = {
            ...options,
            headers
        };

        // if (options.method === 'GET') {
        //     // 如果是 GET 请求，将参数拼接到 URL 中
        //     const queryString = Object.keys(options.params || {}).map(key => `${key}=${options.params[key]}`).join('&');
        //     url += `?${queryString}`;
        // }

        try {
            // app.$message.info('正在请求中...')
            const response = await fetch(url, fetchOptions);
            // 统一处理错误
            if (!response.ok) {
                throw new Error(`HTTP error! Status: ${response.status}`);
            }
            const data = await response.json();
            if (data[resKeys.code] !== resSuccCode) {
                throw new Error(data[resKeys.msg]);
            }
            return {
                code: data[resKeys.code],
                msg: data[resKeys.msg],
                data: data[resKeys.data],
                total: data[resKeys.total],
                orgin: data
            };
        } catch (error) {
            // console.log('Fetch error:', error);
            if (options.catch) {
                //
            } else {
                app.$alert(error.message, '请求接口失败');
                // response.reject(error)
            }
            throw error;
        }
    }
    // 再次基于fetchGet包装一个fetchPost函数，用于post请求
    async function fetchPost(url, data, options = {}) {
        return fetchGet(url, {
            method: 'POST',
            body: JSON.stringify(data),
            ...options
        });
    }

</script>
<!-- VUE 全局实例注册 -->
~{template "public/commonVUE" .}~
~{end}~